package com.dt.platform.oa.service.impl;

import javax.annotation.Resource;

import com.dt.platform.constants.enums.oa.FinCollectStatusEnum;
import com.dt.platform.constants.enums.oa.FinPaymentStatusEnum;
import com.dt.platform.domain.oa.*;
import com.dt.platform.oa.service.*;
import com.github.foxnic.commons.log.Logger;
import org.github.foxnic.web.session.SessionUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.foxnic.dao.entity.ReferCause;
import com.github.foxnic.commons.collection.MapUtil;

import java.math.BigDecimal;
import java.util.Arrays;


import java.util.List;
import com.github.foxnic.api.transter.Result;
import com.github.foxnic.dao.data.PagedList;
import com.github.foxnic.dao.entity.SuperService;
import com.github.foxnic.dao.spec.DAO;
import java.lang.reflect.Field;
import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.sql.expr.ConditionExpr;
import com.github.foxnic.api.error.ErrorDesc;
import com.github.foxnic.dao.excel.ExcelWriter;
import com.github.foxnic.dao.excel.ValidateResult;
import com.github.foxnic.dao.excel.ExcelStructure;
import java.io.InputStream;
import com.github.foxnic.sql.meta.DBField;
import com.github.foxnic.dao.data.SaveMode;
import com.github.foxnic.dao.meta.DBColumnMeta;
import com.github.foxnic.sql.expr.Select;
import java.util.ArrayList;

import org.github.foxnic.web.framework.dao.DBConfigs;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 收款记录服务实现
 * </p>
 * @author 金杰 , maillank@qq.com
 * @since 2025-06-08 19:20:47
*/


@Service("OaFinCollectionRecordService")

public class FinCollectionRecordServiceImpl extends SuperService<FinCollectionRecord> implements IFinCollectionRecordService {


	@Autowired
	private IFinCollectionNoTicketService finCollectionNoTicketService;


	@Autowired
	private IFinInvoicingApplyService finInvoicingApplyService;


	/**
	 * 注入DAO对象
	 * */
	@Resource(name=DBConfigs.PRIMARY_DAO) 
	private DAO dao=null;

	/**
	 * 获得 DAO 对象
	 * */
	public DAO dao() { return dao; }



	@Override
	public Object generateId(Field field) {
		return IDGenerator.getSnowflakeIdString();
	}

	/**
	 * 添加，根据 throwsException 参数抛出异常或返回 Result 对象
	 *
	 * @param finCollectionRecord  数据对象
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 结果 , 如果失败返回 false，成功返回 true
	 */
	@Override
	public Result insert(FinCollectionRecord finCollectionRecord,boolean throwsException) {



		BigDecimal totalAmount=null;
		BigDecimal collectAmount=null;
		if("no_ticket".equals(finCollectionRecord.getOwnerType())){
			FinCollectionNoTicket finCollectionNoTicket=finCollectionNoTicketService.getById(finCollectionRecord.getOwnerId());
			collectAmount=finCollectionNoTicket.getCollectAmount();
			totalAmount=finCollectionNoTicket.getAmount();

			if(FinCollectStatusEnum.PART.code().equals(finCollectionNoTicket.getCollectStatus())
					||FinCollectStatusEnum.WAIT.code().equals(finCollectionNoTicket.getCollectStatus())){
				Logger.info("ticket");
			}else{
				return ErrorDesc.failureMessage("当前单据状态无法进行付款操作");
			}

		}else if("ticket".equals(finCollectionRecord.getOwnerType())){
			FinInvoicingApply finInvoicingApply=finInvoicingApplyService.getById(finCollectionRecord.getOwnerId());
			collectAmount=finInvoicingApply.getCollectAmount();
			totalAmount=finInvoicingApply.getAmount();


			if(FinCollectStatusEnum.PART.code().equals(finInvoicingApply.getCollectStatus())
					||FinCollectStatusEnum.WAIT.code().equals(finInvoicingApply.getCollectStatus())){
				Logger.info("ticket");
			}else{
				return ErrorDesc.failureMessage("当前单据状态无法进行付款操作");
			}
		}else{
			return ErrorDesc.failureMessage("当前类型不正确,类型:"+finCollectionRecord.getOwnerType());
		}

		if(finCollectionRecord.getAmount().compareTo(BigDecimal.ZERO)<=0){
			return ErrorDesc.failureMessage("金额必须大于0");
		}

		if(finCollectionRecord.getAmount().compareTo(totalAmount)>0){
			return ErrorDesc.failureMessage("金额必须小于"+totalAmount+"元");
		}
		finCollectionRecord.setOriginatorId(SessionUser.getCurrent().getActivatedEmployeeId());

		if(finCollectionRecord.getAmount().add(collectAmount).compareTo(totalAmount)>0){
			return ErrorDesc.failureMessage("总金额为:"+totalAmount+",当前支付总金额:"+finCollectionRecord.getAmount().add(collectAmount)+",已超额回款");
		}


		//开始更新主要单据
		Result r=super.insert(finCollectionRecord,throwsException);
		if(r.success()){
			if("no_ticket".equals(finCollectionRecord.getOwnerType())){
				FinCollectionNoTicket finCollectionNoTicket=new FinCollectionNoTicket();
				finCollectionNoTicket.setCollectLastTime(new Date());
				finCollectionNoTicket.setCollectStatus(FinCollectStatusEnum.PART.code());
				finCollectionNoTicket.setId(finCollectionRecord.getOwnerId());
				finCollectionNoTicketService.update(finCollectionNoTicket,SaveMode.NOT_NULL_FIELDS);
				//计算
				dao.execute("update oa_fin_collection_no_ticket set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",finCollectionRecord.getOwnerId(),finCollectionRecord.getOwnerId());
			}else if("ticket".equals(finCollectionRecord.getOwnerType())){
				FinInvoicingApply finInvoicingApply=new FinInvoicingApply();
				finInvoicingApply.setCollectLastTime(new Date());
				finInvoicingApply.setId(finCollectionRecord.getOwnerId());
				finInvoicingApply.setCollectStatus(FinCollectStatusEnum.PART.code());
				finInvoicingApplyService.update(finInvoicingApply,SaveMode.NOT_NULL_FIELDS);
				//计算
				dao.execute("update oa_fin_invoicing_apply set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",finCollectionRecord.getOwnerId(),finCollectionRecord.getOwnerId());
			}
		}
		return r;
	}

	@Override
	public Result action(String id, String action,String ownerType) {
//		FinCollectionRecord finCollectionRecord=this.getById(id);
		if ("no_ticket".equals(ownerType)) {
			dao.execute("update oa_fin_collection_no_ticket set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",id,id);
			FinCollectionNoTicket finCollectionNoTicket=finCollectionNoTicketService.getById(id);
			BigDecimal collectAmount=finCollectionNoTicket.getCollectAmount();
			BigDecimal totalAmount=finCollectionNoTicket.getAmount();
			if("finish".equals(action)){
				if(totalAmount.compareTo(collectAmount)==0){
					finCollectionNoTicket.setCollectStatus(FinCollectStatusEnum.FINISH.code());
					finCollectionNoTicketService.update(finCollectionNoTicket,SaveMode.NOT_NULL_FIELDS);
				}else{
					return ErrorDesc.failureMessage("当前没有全部完成支付");
				}

			}else if("part_finish".equals(action)){
				finCollectionNoTicket.setCollectStatus(FinCollectStatusEnum.PART_FINISH.code());
				finCollectionNoTicketService.update(finCollectionNoTicket,SaveMode.NOT_NULL_FIELDS);
			}else{
				ErrorDesc.failureMessage("错误的动作类型");
			}
		} else if ("ticket".equals(ownerType)) {
			dao.execute("update oa_fin_invoicing_apply set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",id,id);
			FinInvoicingApply finInvoicingApply=finInvoicingApplyService.getById(id);
			BigDecimal collectAmount=finInvoicingApply.getCollectAmount();
			BigDecimal totalAmount=finInvoicingApply.getAmount();
			if("finish".equals(action)){
				if(totalAmount.compareTo(collectAmount)==0){
					finInvoicingApply.setCollectStatus(FinCollectStatusEnum.FINISH.code());
					finInvoicingApplyService.update(finInvoicingApply,SaveMode.NOT_NULL_FIELDS);
				}else{
					return ErrorDesc.failureMessage("当前没有全部完成支付");
				}
			}else if("part_finish".equals(action)){
				finInvoicingApply.setCollectStatus(FinCollectStatusEnum.PART_FINISH.code());
				finInvoicingApplyService.update(finInvoicingApply,SaveMode.NOT_NULL_FIELDS);
			}else{
				ErrorDesc.failureMessage("错误的动作类型");
			}
		}

		return ErrorDesc.success();
	}

	/**
	 * 添加，如果语句错误，则抛出异常
	 * @param finCollectionRecord 数据对象
	 * @return 插入是否成功
	 * */
	@Override
	public Result insert(FinCollectionRecord finCollectionRecord) {
		return this.insert(finCollectionRecord,true);
	}

	/**
	 * 批量插入实体，事务内
	 * @param finCollectionRecordList 实体数据清单
	 * @return 插入是否成功
	 * */
	@Override
	public Result insertList(List<FinCollectionRecord> finCollectionRecordList) {
		return super.insertList(finCollectionRecordList);
	}

	
	/**
	 * 按主键删除收款记录
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdPhysical(String id) {
		FinCollectionRecord finCollectionRecord = new FinCollectionRecord();

		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		finCollectionRecord.setId(id);
		try {
			FinCollectionRecord source = this.getById(id);
			boolean suc = dao.deleteEntity(finCollectionRecord);
			if(suc){
				if ("no_ticket".equals(source.getOwnerType())) {
					dao.execute("update oa_fin_collection_no_ticket set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0) where id=?",source.getOwnerId(),source.getOwnerId());

				} else if ("ticket".equals(source.getOwnerType())) {
					dao.execute("update oa_fin_invoicing_apply set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",source.getOwnerId(),source.getOwnerId());
				}
			}
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}
	
	/**
	 * 按主键删除收款记录
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdLogical(String id) {
		FinCollectionRecord finCollectionRecord = new FinCollectionRecord();

		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		finCollectionRecord.setId(id);
		finCollectionRecord.setDeleted(true);
		finCollectionRecord.setDeleteBy((String)dao.getDBTreaty().getLoginUserId());
		finCollectionRecord.setDeleteTime(new Date());
		try {
			FinCollectionRecord source = this.getById(id);
			boolean suc = dao.updateEntity(finCollectionRecord,SaveMode.NOT_NULL_FIELDS);
			if(suc){
				if ("no_ticket".equals(source.getOwnerType())) {
					dao.execute("update oa_fin_collection_no_ticket set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",source.getOwnerId(),source.getOwnerId());

				} else if ("ticket".equals(source.getOwnerType())) {
					dao.execute("update oa_fin_invoicing_apply set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",source.getOwnerId(),source.getOwnerId());

				}
			}
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}

	/**
	 * 更新，如果执行错误，则抛出异常
	 * @param finCollectionRecord 数据对象
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(FinCollectionRecord finCollectionRecord , SaveMode mode) {
		return this.update(finCollectionRecord,mode,true);
	}

	/**
	 * 更新，根据 throwsException 参数抛出异常或返回 Result 对象
	 * @param finCollectionRecord 数据对象
	 * @param mode 保存模式
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(FinCollectionRecord finCollectionRecord , SaveMode mode,boolean throwsException) {

		BigDecimal totalAmount=null;
		BigDecimal collectAmount=null;
		FinCollectionRecord sourceRecord=this.getById(finCollectionRecord.getId());
		if("no_ticket".equals(finCollectionRecord.getOwnerType())){
			FinCollectionNoTicket finCollectionNoTicket=finCollectionNoTicketService.getById(finCollectionRecord.getOwnerId());
			collectAmount=finCollectionNoTicket.getCollectAmount();
			totalAmount=finCollectionNoTicket.getAmount();

			if(FinCollectStatusEnum.PART.code().equals(finCollectionNoTicket.getCollectStatus())
					||FinCollectStatusEnum.WAIT.code().equals(finCollectionNoTicket.getCollectStatus())){
				Logger.info("ticket");
			}else{
				return ErrorDesc.failureMessage("当前单据状态无法进行付款操作");
			}
		}else if("ticket".equals(finCollectionRecord.getOwnerType())){
			FinInvoicingApply finInvoicingApply=finInvoicingApplyService.getById(finCollectionRecord.getOwnerId());
			collectAmount=finInvoicingApply.getCollectAmount();
			totalAmount=finInvoicingApply.getAmount();

			if(FinCollectStatusEnum.PART.code().equals(finInvoicingApply.getCollectStatus())
					||FinCollectStatusEnum.WAIT.code().equals(finInvoicingApply.getCollectStatus())){
				Logger.info("ticket");
			}else{
				return ErrorDesc.failureMessage("当前单据状态无法进行付款操作");
			}

		}else{
			return ErrorDesc.failureMessage("当前类型不正确,类型:"+finCollectionRecord.getOwnerType());
		}

		if(finCollectionRecord.getAmount().compareTo(BigDecimal.ZERO)<=0){
			return ErrorDesc.failureMessage("金额必须大于0");
		}

		if(finCollectionRecord.getAmount().compareTo(totalAmount)>0){
			return ErrorDesc.failureMessage("金额必须小于"+totalAmount+"元");
		}

		if(!SessionUser.getCurrent().getActivatedEmployeeId().equals(sourceRecord.getOriginatorId())){
			return ErrorDesc.failureMessage("当前操作人员和原操作人员不一致");
		}


		if(finCollectionRecord.getAmount().add(collectAmount).divide(sourceRecord.getAmount()).compareTo(totalAmount)>0){
			return ErrorDesc.failureMessage("总金额为:"+totalAmount+",当前支付总金额:"+finCollectionRecord.getAmount().add(collectAmount)+",已超额回款");
		}


		Result r=super.update(finCollectionRecord , mode , throwsException);

		if(r.isSuccess()) {
			//开始更新主要单据
			if ("no_ticket".equals(finCollectionRecord.getOwnerType())) {
				FinCollectionNoTicket finCollectionNoTicket = new FinCollectionNoTicket();
				finCollectionNoTicket.setCollectLastTime(new Date());
				finCollectionNoTicket.setCollectStatus(FinCollectStatusEnum.PART.code());
				finCollectionNoTicket.setId(finCollectionRecord.getOwnerId());
				finCollectionNoTicketService.update(finCollectionNoTicket, SaveMode.NOT_NULL_FIELDS);
				//计算
				dao.execute("update oa_fin_collection_no_ticket set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",finCollectionRecord.getOwnerId(),finCollectionRecord.getOwnerId());
			} else if ("ticket".equals(finCollectionRecord.getOwnerType())) {
				FinInvoicingApply finInvoicingApply=new FinInvoicingApply();
				finInvoicingApply.setCollectLastTime(new Date());
				finInvoicingApply.setCollectStatus(FinCollectStatusEnum.PART.code());
				finInvoicingApply.setId(finCollectionRecord.getOwnerId());
				finInvoicingApplyService.update(finInvoicingApply, SaveMode.NOT_NULL_FIELDS);
				//计算
				dao.execute("update oa_fin_invoicing_apply set collect_amount=ifnull((select sum(amount) from oa_fin_collection_record where deleted=0 and owner_id=?),0)  where id=?",finCollectionRecord.getOwnerId(),finCollectionRecord.getOwnerId());
			}
		}
		return r;

	}

	/**
	 * 更新实体集，事务内
	 * @param finCollectionRecordList 数据对象列表
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result updateList(List<FinCollectionRecord> finCollectionRecordList , SaveMode mode) {
		return super.updateList(finCollectionRecordList , mode);
	}

	
	/**
	 * 按主键更新收款记录
	 *
	 * @param id 主键
	 * @return 是否更新成功
	 */
	public boolean update(DBField field,Object value , String id) {
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		if(!field.table().name().equals(this.table())) throw new IllegalArgumentException("更新的数据表["+field.table().name()+"]与服务对应的数据表["+this.table()+"]不一致");
		int suc=dao.update(field.table().name()).set(field.name(), value).where().and("id = ? ",id).top().execute();
		return suc>0;
	}

	
	/**
	 * 按主键获取收款记录
	 *
	 * @param id 主键
	 * @return FinCollectionRecord 数据对象
	 */
	public FinCollectionRecord getById(String id) {
		FinCollectionRecord sample = new FinCollectionRecord();
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		sample.setId(id);
		return dao.queryEntity(sample);
	}

	/**
	 * 等价于 queryListByIds
	 * */
	@Override
	public List<FinCollectionRecord> getByIds(List<String> ids) {
		return this.queryListByIds(ids);
	}

	@Override
	public List<FinCollectionRecord> queryListByIds(List<String> ids) {
		return super.queryListByUKeys("id",ids);
	}

	@Override
	public Map<String, FinCollectionRecord> queryMapByIds(List<String> ids) {
		return super.queryMapByUKeys("id",ids, FinCollectionRecord::getId);
	}



	/**
	 * 查询实体集合，默认情况下，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @return 查询结果
	 * */
	@Override
	public List<FinCollectionRecord> queryList(FinCollectionRecordVO sample) {
		return super.queryList(sample);
	}


	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<FinCollectionRecord> queryPagedList(FinCollectionRecordVO sample, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, pageSize, pageIndex);
	}

	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param condition 其它条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<FinCollectionRecord> queryPagedList(FinCollectionRecord sample, ConditionExpr condition, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, condition, pageSize, pageIndex);
	}

	/**
	 * 检查 实体 是否已经存在 , 判断 主键值不同，但指定字段的值相同的记录是否存在
	 *
	 * @param finCollectionRecord 数据对象
	 * @return 判断结果
	 */
	public Boolean checkExists(FinCollectionRecord finCollectionRecord) {
		//TDOD 此处添加判断段的代码
		//boolean exists=super.checkExists(finCollectionRecord, SYS_ROLE.NAME);
		//return exists;
		return false;
	}

	/**
	 * 批量检查引用
	 * @param ids  检查这些ID是否又被外部表引用
	 * */
	@Override
	public <T> Map<T, ReferCause> hasRefers(List<T> ids) {
		// 默认无业务逻辑，返回此行；有业务逻辑需要校验时，请修改并使用已注释的行代码！！！
		return MapUtil.asMap(ids,new ReferCause(false));
		// return super.hasRefers(FoxnicWeb.BPM_PROCESS_INSTANCE.FORM_DEFINITION_ID,ids);
	}





}